﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RaikesSimplexService.SlyFox;
using RaikesSimplexService.DataModel;

namespace DemoApp
{
    class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        /// 
        static void Main(string[] args)
        {
            Solver target = new Solver();

            Model model = new Model();

            LinearConstraint lc1 = new LinearConstraint();
            lc1.Coefficients = new double[2] { 8, 12 };
            lc1.Relationship = new Relationship();
            lc1.Relationship = Relationship.GreaterThanOrEquals;
            lc1.Value = 24;

            LinearConstraint lc2 = new LinearConstraint();
            lc2.Coefficients = new double[2] { 12, 12 };
            lc2.Relationship = new Relationship();
            lc2.Relationship = Relationship.GreaterThanOrEquals;
            lc2.Value = 36;

            LinearConstraint lc3 = new LinearConstraint();
            lc3.Coefficients = new double[2] { 2, 1 };
            lc3.Relationship = new Relationship();
            lc3.Relationship = Relationship.GreaterThanOrEquals;
            lc3.Value = 4;

            LinearConstraint lc4 = new LinearConstraint();
            lc4.Coefficients = new double[2] { 1, 1 };
            lc4.Relationship = new Relationship();
            lc4.Relationship = Relationship.LessThanOrEquals;
            lc4.Value = 5;

            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(lc1);
            constraints.Add(lc2);
            constraints.Add(lc3);
            constraints.Add(lc4);

            model.Constraints = constraints;

            Goal goal = new Goal();
            goal.Coefficients = new double[2] { 0.2, 0.3 };

            model.Goal = goal;

            model.GoalKind = new GoalKind();
            model.GoalKind = GoalKind.Minimize;

            double[] actual;
            actual = target.Solve(model).Values;

            Console.WriteLine("Example 1: ");
            Console.WriteLine("The values are: ");
            for (int i = 0; i < actual.Length; i++)
            {
                Console.Write("X" + (i+1) + ": " + actual[i] + ", ");
            }
            Console.WriteLine();
            double optval = 0;
            double temp = 0;
            for (int j = 0; j < actual.Length; j++)
            {
                temp = actual[j] * model.Goal.Coefficients[j];
                optval += temp;
            }
            Console.WriteLine("The optimal value for Z is: " + optval);
            Console.WriteLine("");

            {
                Solver target1 = new Solver();

                Model model1 = new Model();

                LinearConstraint lc11 = new LinearConstraint();
                lc11.Coefficients = new double[5] { 1, 2, 2, 1, 0 };
                lc11.Relationship = new Relationship();
                lc11.Relationship = Relationship.Equals;
                lc11.Value = 8;

                LinearConstraint lc21 = new LinearConstraint();
                lc21.Coefficients = new double[5] { 3, 4, 1, 0, 1 };
                lc21.Relationship = new Relationship();
                lc21.Relationship = Relationship.Equals;
                lc21.Value = 7;

                List<LinearConstraint> constraints1 = new List<LinearConstraint>();
                constraints1.Add(lc11);
                constraints1.Add(lc21);

                model1.Constraints = constraints1;

                Goal goal1 = new Goal();
                goal1.Coefficients = new double[5] { 5, 2, 3, -1, 1 };

                model1.Goal = goal1;

                model1.GoalKind = new GoalKind();
                model1.GoalKind = GoalKind.Maximize;

                Console.WriteLine("Example 2: ");
                double[] actual1;
                actual1 = target.Solve(model1).Values;
                Console.WriteLine("The values are: ");
                for (int i = 0; i < actual1.Length; i++)
                {
                    Console.Write("X"+ (i+1) +": " + actual1[i] + ", ");
                }
                Console.WriteLine();

                double optval1 = 0;
                double temp1 = 0;
                for (int j = 0; j < actual1.Length; j++)
                {
                    temp1 = actual1[j] * model1.Goal.Coefficients[j];
                    optval1 += temp1;
                }
                Console.WriteLine("The optimal value for Z is: " + optval1);
                Console.WriteLine("");

                Solver target2 = new Solver();

                Model model2 = new Model();

                LinearConstraint lc12 = new LinearConstraint();
                lc12.Coefficients = new double[3] { 1, -1, 0 };
                lc12.Relationship = new Relationship();
                lc12.Relationship = Relationship.LessThanOrEquals;
                lc12.Value = 5;

                LinearConstraint lc22 = new LinearConstraint();
                lc22.Coefficients = new double[3] { -2, 1, 0 };
                lc22.Relationship = new Relationship();
                lc22.Relationship = Relationship.LessThanOrEquals;
                lc22.Value = 3;

                LinearConstraint lc32 = new LinearConstraint();
                lc32.Coefficients = new double[3] { 0, 1, -2 };
                lc32.Relationship = new Relationship();
                lc32.Relationship = Relationship.LessThanOrEquals;
                lc32.Value = 5;

                List<LinearConstraint> constraints2 = new List<LinearConstraint>();
                constraints2.Add(lc1);
                constraints2.Add(lc2);
                constraints2.Add(lc3);

                model2.Constraints = constraints2;

                Goal goal2 = new Goal();
                goal2.Coefficients = new double[3] { 0, 2, 1 };

                model2.Goal = goal2;

                model2.GoalKind = new GoalKind();
                model2.GoalKind = GoalKind.Maximize;
                Console.WriteLine("Example 3: ");
                if (target.Solve(model2).TimedOut)
                {
                    Console.WriteLine("The demo has timed out, meaning the LP is unbounded.");
                }
                else
                {
                    Console.WriteLine("There was a problem.");
                }
                Console.WriteLine("");
                 Solver target3 = new Solver();

            Model model3 = new Model();

            LinearConstraint lc13 = new LinearConstraint();
            lc13.Coefficients = new double[2] { 1, 2 };
            lc13.Relationship = new Relationship();
            lc13.Relationship = Relationship.LessThanOrEquals;
            lc13.Value = 2;

            LinearConstraint lc23 = new LinearConstraint();
            lc23.Coefficients = new double[2] { 2, 4 };
            lc23.Relationship = new Relationship();
            lc23.Relationship = Relationship.GreaterThanOrEquals;
            lc23.Value = 8;

            List<LinearConstraint> constraints3 = new List<LinearConstraint>();
            constraints3.Add(lc13);
            constraints3.Add(lc23);

            model3.Constraints = constraints3;

            Goal goal3 = new Goal();
            goal3.Coefficients = new double[2] { 3, -2 };

            model3.Goal = goal3;

            model3.GoalKind = new GoalKind();
            model3.GoalKind = GoalKind.Maximize;

            Solution actual3 = target.Solve(model3);
            Console.WriteLine("Example 4: ");
            if (actual3.IsInfeasible)
            {
                Console.WriteLine("This LP is infeasible.");
            }
            else
            {
                Console.WriteLine("There was a problem.");
            }

                
                }          
            }
        }
    }

